# Create a new group channel

Creates a new channel within the specified group. Requires group administrator privileges. The channel's privacy is constrained by the parent group's privacy settings (private groups can only have private channels). The first channel created is automatically designated as both primary and auto-subscribe. Channels can have both scoped usernames (group-specific) and optional global usernames (platform-wide). Note: Avatar and header images must be set via the update endpoint after creation.

RBAC: requires GroupChannels.Manage

Endpoint: POST /api/v1/groups/{groupId}/channels
Version: 1.0
Security: header

## Query parameters:

  - `htmlContent` (any)
    Returns text as html if true or original text if false. Applicable only to local posts and users. Default is true.

## Path parameters:

  - `groupId` (string, required)
    The unique identifier of the group
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

## Request fields (application/json):

  - `username` (string, required)
    Channel identifier scoped to the group. Must be unique within the group. Used to generate the channel's username in format 'groupname:channelname' for private channels.
    Example: "news"

  - `displayName` (string, required)
    Human-readable display name for the channel. Shown in channel listings and UI.
    Example: "Group News"

  - `summary` (string)
    Brief description of the channel's purpose and content (max 1024 characters)
    Example: "Read group news and announcements here"

  - `privacy` (string)
    Channel privacy level. PUBLIC channels are visible to everyone, PRIVATE channels only to group members. Private groups can only have private channels.
    Enum: "PUBLIC", "PRIVATE"

  - `isPrimary` (boolean)
    Whether this channel should be the primary channel for the group. Only one primary channel allowed per group. The first channel created is automatically made primary.

  - `isAutoSubscribe` (boolean)
    Whether this channel should be an auto-subscribe channel. Auto-subscribe channels are automatically followed by new group members. The first channel created is automatically made auto-subscribe.
    Example: true

  - `globalUsername` (string,null)
    Global username for public channels. Must be unique across the entire platform. Allows the channel to be accessed via '@globalUsername' in addition to the scoped username. Only available for public channels in public groups.
    Example: "platform-news"

  - `color` (string,null)
    Theme color for the channel in 6-character HEX format with # prefix
    Example: "#FF5733"

  - `subscribeExistingMembers` (boolean,null)
    When creating an auto-subscribe channel, whether to subscribe all existing group members. Default: true.

  - `kind` (string)
    Kind of channel: 'channel' for regular group channels, 'category' for forum categories. When set to 'category', the 'wellesley.group.forum' namespace is written to app_meta, making the channel filterable via appMetaHas/appMetaLacks. Default: channel.
    Enum: "channel", "category"

## Response 200 fields (application/json):

  - `id` (string, required)
    internal id of this user
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `username` (string, required)
    unique user name
    Example: "john_smith"

  - `domain` (string, required)
    User's domain
    Example: "wlsly1.net"

  - `local` (boolean, required)
    Whether this user is local to this server

  - `displayName` (string, required)
    full name of the user
    Example: "John Smith"

  - `uri` (string, required)
    URI of this user
    Example: "https://wlsly1.net/users/john_smith"

  - `avatar` (object,null)
    User's avatar

  - `avatar.uploadId` (string, required)
    Internal id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `avatar.uploaderId` (string,null)
    User who physically uploaded this file. Null for platform-owned uploads (e.g., default covers). This is an audit/meta field — use ownerId for authorization.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `avatar.ownerId` (string, required)
    Entity that owns this upload (user, channel/group, or event). TypeID prefix indicates the owner type.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `avatar.attachedToId` (string,null)
    Entity this upload is attached to (e.g., a post or event). NULL for standalone uploads like avatars, covers, or media library items.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `avatar.uploadType` (string, required)
    Type of the upload
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `avatar.meta` (object)
    Meta data

  - `avatar.meta.blurhash` (string,null)

  - `avatar.meta.name` (string,null)

  - `avatar.meta.altText` (string,null)

  - `avatar.size` (integer, required)
    Size in bytes of all the files in this upload

  - `avatar.files` (array, required)
    List of all the files this upload has

  - `avatar.files.uri` (string,null, required)
    Full url of the file

  - `avatar.files.fileId` (string, required)
    File id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `avatar.files.extension` (string, required)
    File extension
    Example: "mp4"

  - `avatar.files.original` (boolean, required)
    true if this file is original, false if it is a derivative

  - `avatar.files.meta` (object, required)
    File metadata. Contains optional values for width, height etc.

  - `avatar.files.meta.duration` (number,null)
    Video duration in seconds

  - `avatar.files.meta.width` (integer,null)
    Media width

  - `avatar.files.meta.height` (integer,null)
    Media height

  - `avatar.files.meta.codec` (string,null)
    Video codec

  - `avatar.files.meta.rotate` (integer,null)
    Rotation in degrees

  - `avatar.files.size` (integer, required)
    File size in bytes

  - `avatar.files.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `avatar.files.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `avatar.files.type` (string, required)
    File type
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `avatar.tags` (array, required)
    List of tags attached to upload
    Enum: "Post", "Avatar", "Header", "Album", "Emoji", "Event"

  - `avatar.error` (string,null)
    Upload processing error

  - `avatar.cached` (boolean)
    true if cached

  - `avatar.logs` (string,null)
    Logs

  - `avatar.remote` (boolean)
    true if this upload is remote

  - `avatar.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `avatar.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `createdAt` (string, required)
    User's creation time
    Example: "2022-03-10T16:15:50Z"

  - `state` (string, required)
    User's moderation state
    Enum: "REGULAR", "SENSITIVE", "LIMITED", "SUSPENDED"

  - `relationship` (object,null)
    Relationship with this user

  - `relationship.following` (string,null)
    Does the viewer follow the target?
    Enum: "PENDING", "ACCEPTED", "REJECTED"

  - `relationship.followed` (string,null)
    Does the target follow the viewer?
    Enum: "PENDING", "ACCEPTED", "REJECTED"

  - `relationship.blocked` (boolean,null)
    Viewer blocked the target

  - `relationship.blockedBy` (boolean,null)
    Target blocked the viewer

  - `relationship.muted` (object,null)
    Viewer mutes the target

  - `relationship.muted.state` (boolean, required)

  - `relationship.muted.expiresAt` (string,null)
    Example: "2022-03-10T16:15:50Z"

  - `relationship.note` (string,null)
    Viewer's private note about the target

  - `entityType` (string)
    Entity type: USER, BOT, APPLICATION, GROUP_CHANNEL
    Enum: "USER", "BOT", "APPLICATION", "GROUP_CHANNEL"

  - `appMeta` (object)
    Structured metadata (channel flags, channel color, etc.)

  - `groupId` (string,null)
    Group ID if this is a group channel or group user.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupPrivacy` (string,null)
    Privacy of this channel in a group.
    Enum: "PUBLIC", "PRIVATE"

  - `groupUserName` (string,null)
    Name of the channel inside a group

  - `actorType` (string,null)
    Whether this user is a person, application or a service
    Enum: "Application", "Group", "Organization", "Person", "Service"

  - `summary` (string, required)
    User's summary or bio
    Example: "Pixels are my paint, code is my canvas, creativity is my brush."

  - `stats` (object)
    User stats

  - `stats.posts` (integer, required)
    Total number of posts

  - `stats.postsLast24h` (integer, required)
    Posts created in the last 24 hours

  - `stats.totalStorageBytes` (integer, required)
    Total uploaded bytes

  - `stats.comments` (integer, required)
    Total number of comments

  - `stats.avgPostsPerDay` (number, required)
    Average posts per day over the last 30 days

  - `stats.avgBytesPerDay` (number, required)
    Average uploaded bytes per day over the last 30 days

  - `stats.followers` (integer, required)
    number of followers

  - `stats.following` (integer, required)
    number of following

  - `stats.followingHidden` (boolean, required)
    privacy setting to hide followings

  - `stats.totalEvents` (integer, required)
    total number of events (group/user) emitted

  - `fields` (object)
    User fields

  - `header` (object,null)
    User's header

  - `header.uploadId` (string, required)
    Internal id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `header.uploaderId` (string,null)
    User who physically uploaded this file. Null for platform-owned uploads (e.g., default covers). This is an audit/meta field — use ownerId for authorization.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `header.ownerId` (string, required)
    Entity that owns this upload (user, channel/group, or event). TypeID prefix indicates the owner type.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `header.attachedToId` (string,null)
    Entity this upload is attached to (e.g., a post or event). NULL for standalone uploads like avatars, covers, or media library items.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `header.uploadType` (string, required)
    Type of the upload
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `header.meta` (object)
    Meta data

  - `header.meta.blurhash` (string,null)

  - `header.meta.name` (string,null)

  - `header.meta.altText` (string,null)

  - `header.size` (integer, required)
    Size in bytes of all the files in this upload

  - `header.files` (array, required)
    List of all the files this upload has

  - `header.files.uri` (string,null, required)
    Full url of the file

  - `header.files.fileId` (string, required)
    File id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `header.files.extension` (string, required)
    File extension
    Example: "mp4"

  - `header.files.original` (boolean, required)
    true if this file is original, false if it is a derivative

  - `header.files.meta` (object, required)
    File metadata. Contains optional values for width, height etc.

  - `header.files.meta.duration` (number,null)
    Video duration in seconds

  - `header.files.meta.width` (integer,null)
    Media width

  - `header.files.meta.height` (integer,null)
    Media height

  - `header.files.meta.codec` (string,null)
    Video codec

  - `header.files.meta.rotate` (integer,null)
    Rotation in degrees

  - `header.files.size` (integer, required)
    File size in bytes

  - `header.files.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `header.files.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `header.files.type` (string, required)
    File type
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `header.tags` (array, required)
    List of tags attached to upload
    Enum: "Post", "Avatar", "Header", "Album", "Emoji", "Event"

  - `header.error` (string,null)
    Upload processing error

  - `header.cached` (boolean)
    true if cached

  - `header.logs` (string,null)
    Logs

  - `header.remote` (boolean)
    true if this upload is remote

  - `header.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `header.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `deleted` (boolean,null)

  - `emojis` (array,null)

  - `emojis.shortcode` (string, required)

  - `emojis.category` (string,null, required)

  - `emojis.url` (string, required)

  - `emojis.staticUrl` (string, required)

  - `emojis.visibleInPicker` (boolean, required)

  - `location` (object,null)
    User's location, geo and name

  - `location.geo` (object,null, required)
    Coordinates and other geo data

  - `location.geo.latitude` (number, required)

  - `location.geo.longitude` (number, required)

  - `location.geo.altitude` (number,null)

  - `location.geo.accuracy` (number,null)

  - `location.geo.verticalAccuracy` (number,null)

  - `location.geo.speed` (number,null)

  - `location.geo.bearing` (number,null)

  - `location.geo.timestamp` (integer,null)

  - `location.name` (string,null, required)

  - `location.autoUpdate` (boolean, required)

  - `location.show` (boolean, required)

  - `timezone` (object,null)
    User's timezone

  - `timezone.ianaTimezone` (string,null, required)

  - `timezone.autoUpdate` (boolean, required)

  - `timezone.show` (boolean, required)

  - `birthday` (object,null)
    User's birthday

  - `birthday.date` (string,null, required)
    Example: "2022-03-10T16:15:50Z"

  - `birthday.show` (string, required)
    Enum: "NONE", "YEAR", "FULL", "DATE"

  - `software` (string, required)
    Software platform type (wellesley, mastodon, threads.net)
    Example: "wellesley"

  - `groupAvatar` (object,null)
    Group avatar (only present for group channels)

  - `groupAvatar.uploadId` (string, required)
    Internal id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupAvatar.uploaderId` (string,null)
    User who physically uploaded this file. Null for platform-owned uploads (e.g., default covers). This is an audit/meta field — use ownerId for authorization.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupAvatar.ownerId` (string, required)
    Entity that owns this upload (user, channel/group, or event). TypeID prefix indicates the owner type.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupAvatar.attachedToId` (string,null)
    Entity this upload is attached to (e.g., a post or event). NULL for standalone uploads like avatars, covers, or media library items.
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupAvatar.uploadType` (string, required)
    Type of the upload
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `groupAvatar.meta` (object)
    Meta data

  - `groupAvatar.meta.blurhash` (string,null)

  - `groupAvatar.meta.name` (string,null)

  - `groupAvatar.meta.altText` (string,null)

  - `groupAvatar.size` (integer, required)
    Size in bytes of all the files in this upload

  - `groupAvatar.files` (array, required)
    List of all the files this upload has

  - `groupAvatar.files.uri` (string,null, required)
    Full url of the file

  - `groupAvatar.files.fileId` (string, required)
    File id
    Example: "us_01hxcvk1hjexere4pvtrj0ymqq"

  - `groupAvatar.files.extension` (string, required)
    File extension
    Example: "mp4"

  - `groupAvatar.files.original` (boolean, required)
    true if this file is original, false if it is a derivative

  - `groupAvatar.files.meta` (object, required)
    File metadata. Contains optional values for width, height etc.

  - `groupAvatar.files.meta.duration` (number,null)
    Video duration in seconds

  - `groupAvatar.files.meta.width` (integer,null)
    Media width

  - `groupAvatar.files.meta.height` (integer,null)
    Media height

  - `groupAvatar.files.meta.codec` (string,null)
    Video codec

  - `groupAvatar.files.meta.rotate` (integer,null)
    Rotation in degrees

  - `groupAvatar.files.size` (integer, required)
    File size in bytes

  - `groupAvatar.files.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `groupAvatar.files.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `groupAvatar.files.type` (string, required)
    File type
    Enum: "VIDEO", "IMAGE", "AUDIO", "DOCUMENT", "OTHER"

  - `groupAvatar.tags` (array, required)
    List of tags attached to upload
    Enum: "Post", "Avatar", "Header", "Album", "Emoji", "Event"

  - `groupAvatar.error` (string,null)
    Upload processing error

  - `groupAvatar.cached` (boolean)
    true if cached

  - `groupAvatar.logs` (string,null)
    Logs

  - `groupAvatar.remote` (boolean)
    true if this upload is remote

  - `groupAvatar.createdAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `groupAvatar.updatedAt` (string, required)
    Example: "2022-03-10T16:15:50Z"

  - `groupName` (string,null)
    Group name (only present for group channels)

  - `groupDisplayName` (string,null)
    Group display name (only present for group channels)

  - `syncState` (string,null)
    Sync state for remote users (null for local users). SHALLOW_SYNCED = profile fetched, SYNC_IN_PROGRESS = deep sync running, DEEP_SYNCED = full outbox fetched, DEEP_SYNC_FAILED = deep sync failed
    Enum: "SHALLOW_SYNCED", "SYNC_IN_PROGRESS", "DEEP_SYNCED", "DEEP_SYNC_FAILED"

  - `deepSyncedAt` (string,null)
    When the last deep sync completed (null if never deep-synced)
    Example: "2022-03-10T16:15:50Z"

  - `followApproval` (string, required)
    Follow approval mode: AUTO_APPROVE, MANUALLY_APPROVES, or UNKNOWN
    Enum: "AUTO_APPROVE", "MANUALLY_APPROVES", "UNKNOWN"

  - `groupPrimary` (boolean,null)
    true if this is primary group channel.

  - `groupAutoSubscribe` (boolean,null)
    true if this is auto-subscribe group channel.

  - `channel` (boolean, required)
    Whether this is a channel or a user. Deprecated: use 'entityType' instead.


## Response 400 fields
